package com.gtenacg.cartoonservice.controller;

import com.gtenacg.cartoonservice.common.Result;
import com.gtenacg.cartoonservice.common.annotation.CheckToken;
import com.gtenacg.cartoonservice.pojo.model.*;
import com.gtenacg.cartoonservice.pojo.vo.CartoonVo;
import com.gtenacg.cartoonservice.pojo.vo.NovelVo;
import com.gtenacg.cartoonservice.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/novel")
public class NovelController {
    private final NovelService novelService;
    private final NovelTypeService typeService;
    private final AuthorService authorService;
    private final RelationNovelTypeService relationTypeService;
    private final RelationNovelAuthorService relationAuthorService;

    @GetMapping("/list")
    public Result<List<Novel>> list() {
        log.info("获取电子书列表");
        List<Novel> list = novelService.list();
        return Result.success(list);
    }

    @GetMapping("/search")
    public Result<List<Novel>> search(
            @RequestParam(required = false) String name
    ) {
        log.info("获取电子书列表, name:{}", name);
        List<Novel> list = novelService.search(name);
        return Result.success(list);
    }

    @GetMapping
    public Result<List<NovelVo>> listToVo(
            @RequestParam(required = false) List<Integer> types
    ) {
        log.info("获取电子书视图列表, types:{}", types);

        List<Novel> novels = null;

        if (types == null || types.isEmpty()) {
            novels = novelService.list();
        } else {
            List<RelationNovelType> byTids = relationTypeService.getByTids(types);
            List<Integer> nids = byTids.stream()
                    .map(RelationNovelType::getNid)
                    .toList();
            novels = novelService.getByNids(nids);
        }
        List<NovelVo> list = novelsToVo(novels);


        return Result.success(list);
    }

    @GetMapping("/searchVo")
    public Result<List<NovelVo>> searchVo(@RequestParam String searchVal) {
        log.info("获取电子书视图列表, SearchVal:{}", searchVal);

        List<Novel> novels = novelService.search(searchVal);
        if (novels.isEmpty()) {
            return Result.success(new ArrayList<>());
        }
        List<NovelVo> list = novelsToVo(novels);
        return Result.success(list);
    }

    @GetMapping("/randomVo")
    public Result<List<NovelVo>> randomVo(
            @RequestParam(required = false, defaultValue = "4") Integer num
    ) {
        log.info("获取随机的电子书视图列表, num:{}", num);

        List<Novel> novels = novelService.random(num);
        List<NovelVo> list = novelsToVo(novels);
        return Result.success(list);
    }

    @GetMapping("/{nids}")
    public Result<List<NovelVo>> getVoByNids(@PathVariable List<Integer> nids) {
        log.info("获取指定id为 {} 的视图列表", nids);

        List<Novel> novels = novelService.getByNids(nids);
        List<NovelVo> list = novelsToVo(novels);

        return Result.success(list);
    }

    @GetMapping("/chapter/{nid}")
    public Result<List<String>> getChapterListByCid(@PathVariable Integer nid) {
        log.info("获取指定ID为 {} 的章节信息", nid);

        ArrayList<Integer> nids = new ArrayList<>();
        nids.add(nid);

        List<Novel> novels = novelService.getByNids(nids);
        List<String> chapterList = novelService.getChapterList(novels.get(0));

        return Result.success(chapterList);
    }

    @CheckToken
    @PostMapping
    public Result<Integer> insert(@RequestBody Novel novel) {
        log.info("新增电子书 {}", novel);
        Integer id = null;
        try {
            id = novelService.insert(novel);
        } catch (DuplicateKeyException e) {
            return new Result<>(HttpStatus.CONFLICT.value(), "Duplicate_Key", null);
        }
        return Result.success(id);
    }

    @CheckToken
    @PutMapping
    public Result<Void> update(@RequestBody Novel novel) {
        log.info("更新电子书 {}", novel);
        novelService.update(novel);
        return Result.success();
    }

    @CheckToken
    @DeleteMapping("/{nids}")
    public Result<Void> delete(@PathVariable List<Integer> nids) {
        log.info("删除小说 {}", nids);
        novelService.delete(nids);
        return Result.success();
    }


    /**
     * 将列表转化成视图列表
     */
    private List<NovelVo> novelsToVo(List<Novel> novels) {
        if (novels.isEmpty()) {
            return null;
        }
        List<Integer> nids = novels.stream()
                .map(Novel::getNid)
                .toList();

        List<NovelType> types = typeService.list();
        List<Author> authors = authorService.list();
        List<RelationNovelType> relationTypes = relationTypeService.getByNids(nids);
        List<RelationNovelAuthor> relationAuthors = relationAuthorService.getByNids(nids);

        return novelService.assembleNovelVo(novels, types, relationTypes, authors, relationAuthors);
    }

}
